/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rie06.openvoip.server;

import com.rie06.openvoip.User;
import com.rie06.openvoip.client.Client;
import com.rie06.openvoip.client.IHM.home.InterfaceClient;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

/**
 *
 * @author clement
 */
public class Server implements Runnable {

    private Client client;
    private InterfaceClient ihm;
    private ServerConfig serverConfig;
    private Integer port;
    private ServerSocket serverSocket;
    private Map usersList;
    private Thread thread;
    private static final Logger logger = Logger.getLogger(Server.class);

    public Server() {
        port = 1995;
        getServerConfiguration();
        initialization();
    }

    public Server(Integer port) {
        this.port = port;
        serverConfig = new ServerConfig();
        initialization();
    }

       /**
         * Récupère la configuration du serveur
         */
    
    private void getServerConfiguration() {
        String configFile = System.getProperty("user.home") + "/.config/OpenVoip/Server.config";
        boolean exists = (new File(configFile)).exists();
        if (!exists) {
            FileOutputStream fout = null;
            try {
                //generate UUID and serialize config
                serverConfig = new ServerConfig();
                fout = new FileOutputStream(configFile);
                ObjectOutputStream oos;
                oos = new ObjectOutputStream(fout);
                oos.writeObject(serverConfig);
                oos.close();
                logger.log(Level.INFO, "Generate server config with UUID: " + serverConfig.getId().toString());
            } catch (FileNotFoundException ex) {
                java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (IOException ex) {
                java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } finally {
                try {
                    fout.close();
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
                }
            }
        } else {
            ObjectInputStream ois = null;
            //unserialize config file
            try {
                FileInputStream fin;
                fin = new FileInputStream(configFile);
                ois = new ObjectInputStream(fin);
                serverConfig = (ServerConfig) ois.readObject();
                ois.close();
                logger.log(Level.INFO, "Get server config, UUID: " + serverConfig.getId().toString());
            } catch (IOException ex) {
                java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (ClassNotFoundException ex) {
                java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);

            } finally {
                try {
                    ois.close();
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
                }
            }
        }
    }

        /**
         * Initialize le serveur 
         */
    
    private void initialization() {
        try {

            serverSocket = new ServerSocket(port);

            usersList = new HashMap();

            thread = new Thread(this);
            thread.start();

        } catch (IOException ex) {
            logger.log(Level.FATAL, ex);
        }
    }

    public void setClient(Client client) {
        this.client = client;
    }

    public void setIhm(InterfaceClient ihm) {
        this.ihm = ihm;
    }

    public Map getUsersList() {
        return usersList;
    }

    public Client getClient() {
        return client;
    }

    public InterfaceClient getIhm() {
        return ihm;
    }
    
    public Integer getPort() {
        return port;
    }

    public ServerConfig getServerConfig() {
        return serverConfig;
    }
    
    public void addFromClient(Socket socket, ObjectInput inputTCP, ObjectOutput outputTCP, User user){
        new ServerTCPThread(this, socket, inputTCP, outputTCP, user);
    }

    public void run() {
        logger.log(Level.INFO, "Server Started on port: " + port);
        while (true) {
            try {
                new ServerTCPThread(this, serverSocket.accept());
            } catch (IOException ex) {
                logger.log(Level.FATAL, ex);
            }
        }
    }
}
